package com.wnxy.sddfp.trade.service.impl;
import cn.hutool.core.bean.BeanUtil;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wnxy.sddfp.api.bank.TradeLogApi;
import com.wnxy.sddfp.api.system.UserApi;
import com.wnxy.sddfp.common.exception.Assert;
import com.wnxy.sddfp.common.model.dto.trade.BorrowRecordDTO;
import com.wnxy.sddfp.common.model.enums.BorrowStatusEnums;
import com.wnxy.sddfp.common.model.enums.PrefixEnums;
import com.wnxy.sddfp.common.model.page.PageVo;
import com.wnxy.sddfp.common.model.query.BorrowRecordQuery;
import com.wnxy.sddfp.common.model.vo.trade.BorrowRecordVo;
import com.wnxy.sddfp.common.model.vo.trade.BorrowSyncRecordVo;
import com.wnxy.sddfp.common.model.vo.user.UserInfoVo;
import com.wnxy.sddfp.common.result.Result;
import com.wnxy.sddfp.common.result.enums.impl.ResultCode;
import com.wnxy.sddfp.common.util.TokenUtils;
import com.wnxy.sddfp.common.util.UniqueIdGenerator;
import com.wnxy.sddfp.trade.entity.BorrowRecord;
import com.wnxy.sddfp.trade.mapper.BorrowRecordMapper;
import com.wnxy.sddfp.trade.service.IBorrowRecordService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

/**
 * <p>
 * 借款信息表 服务实现类
 * </p>
 *
 * @author Jet
 * @since 2024-02-20
 */
@Service
@Slf4j
public class BorrowRecordServiceImpl extends ServiceImpl<BorrowRecordMapper, BorrowRecord> implements IBorrowRecordService {

    private final UserApi userApi;
    private final TradeLogApi tradeLogApi;
    public BorrowRecordServiceImpl(UserApi userApi, TradeLogApi tradeLogApi) {
        this.userApi = userApi;
        this.tradeLogApi = tradeLogApi;
    }

    @Override
    public void addBorrowRecord(BorrowRecordDTO borrowRecordDTO) {
        //获取token中用户id
        Long userId = TokenUtils.getTokenUserId();

        //根据用户id查询用户信息:（用户编码、用户名、身份证号码）; openfein远程调用
        Result<UserInfoVo> userInfoVoResult = userApi.findById(userId);
        Assert.error(userInfoVoResult == null || userInfoVoResult.getCode() != ResultCode.SUCCESS.getCode(),ResultCode.DATA_IS_WRONG);
        UserInfoVo userInfoVo = userInfoVoResult.getData();

        //保存借款记录业务处理
        BorrowRecord br = new BorrowRecord();
        br.setUserId(userId);
        br.setUserCode(userInfoVo.getUserCode());
        br.setPeriod(borrowRecordDTO.getPeriod());
        br.setAmount(borrowRecordDTO.getAmount());
        br.setBorrowRecordNo(UniqueIdGenerator.generator(PrefixEnums.BO.getPrefix()));
        // 张山先生的第1次借款
        br.setName(this.getBorrowName(userInfoVo));
        br.setDescription("无");
        br.setInvestRate(new BigDecimal("10"));
        br.setBorrowerRate(new BigDecimal("10"));
        br.setCommissionRate(new BigDecimal("10"));
        br.setRepaymentWay("DEBJ");
        br.setBorrowStatus(BorrowStatusEnums.NEW.getCode());
        br.setCreateDate(new Date());
        br.setModifyDate(new Date());
        br.setStatus(false);
        this.save(br);
    }

    private String getBorrowName(UserInfoVo userInfoVo) {
        // 判断身份证长度
        String identityCode = userInfoVo.getIdentityCode();
        Assert.error(identityCode == null ||
                identityCode.length() != 18,ResultCode.DATA_IS_WRONG);
        // 查询用户第几次借款
        long count = this.count(
                Wrappers.lambdaQuery(BorrowRecord.class)
                        .eq(BorrowRecord::getUserCode, userInfoVo.getUserCode()));
        // 身份证第17位是性别
        int n = Integer.parseInt(identityCode.substring(16,17));
        StringBuffer sb = new StringBuffer();
        sb.append(userInfoVo.getUserName());
        sb.append(n % 2 == 0 ? "女士" : "先生");
        sb.append("的第" + (count + 1) + "次借款");
        return sb.toString();
    }

    @Override
    public PageVo<BorrowRecordVo> borrowRecordQuery(
            Integer current, Integer size, BorrowRecordQuery borrowRecordQuery) {

        // 构造查询条件
        LambdaQueryWrapper<BorrowRecord> wrapper = Wrappers.lambdaQuery(BorrowRecord.class);
        wrapper.eq(StringUtils.hasText(borrowRecordQuery.getBorrowStatus()),BorrowRecord::getBorrowStatus,borrowRecordQuery.getBorrowStatus());
        wrapper.like(StringUtils.hasText(borrowRecordQuery.getName()),BorrowRecord::getName,borrowRecordQuery.getName());
        wrapper.ge(borrowRecordQuery.getStartPeriod() != null,BorrowRecord::getPeriod,borrowRecordQuery.getStartPeriod());
        wrapper.le(borrowRecordQuery.getEndPeriod() != null,BorrowRecord::getPeriod,borrowRecordQuery.getEndPeriod());
        // 分页条件查询
        Page<BorrowRecord> page = this.page(new Page<>(current, size), wrapper);
        List<BorrowRecord> records = page.getRecords();
        // 转换
        List<BorrowRecordVo> voList = records.stream()
                .map(borrowRecord -> BeanUtil.copyProperties(borrowRecord, BorrowRecordVo.class))
                .collect(Collectors.toList());
        // 封装PageVo
        PageVo<BorrowRecordVo> pageVo = new PageVo<>();
        pageVo.setList(voList);
        pageVo.setTotal(page.getTotal());
        pageVo.setPageNum(page.getCurrent());
        pageVo.setPageSize(page.getSize());

        return pageVo;
    }

    @Override
    public void verifyStatus(Long borrowRecordId, String status) {
        // 生成流水号并更新借款记录表,如果borrow_record表的REQ_CODE流水号已经生成过，就不需要重新重新
        BorrowRecord borrowRecord = this.getById(borrowRecordId);
        if (StringUtils.isEmpty(borrowRecord.getReqCode())) {
            String reqCode = UniqueIdGenerator.generator(PrefixEnums.REQ.getPrefix());
            this.update(Wrappers.lambdaUpdate(BorrowRecord.class)
                    .set(BorrowRecord::getReqCode, reqCode)
                    .eq(BorrowRecord::getId, borrowRecordId)
            );
            // 设置流水号
            borrowRecord.setReqCode(reqCode);
        }

        // 调用托管代理服务同步借款信息, 传入参数: BorrowSyncRecordVo
        BorrowSyncRecordVo borrowSyncRecordVo =
                BeanUtil.copyProperties(borrowRecord,BorrowSyncRecordVo.class);

        // 远程调用
        Result result = tradeLogApi.sysncBorrowRecord(borrowSyncRecordVo);

        // 根据远程调用结果，返回200状态码表示业务执行成功，修改BorrowRecord表的status=1、borrow_status为SYNC
        if (result.getCode() == ResultCode.SUCCESS.getCode()) {
            // 修改借款记录数据的状态
            this.update(Wrappers.lambdaUpdate(BorrowRecord.class)
                    .set(BorrowRecord::getStatus, status)
                    .set(BorrowRecord::getBorrowStatus, BorrowStatusEnums.SYNC.getCode())
                    .eq(BorrowRecord::getId, borrowRecordId)
            );
        }
    }
}














